﻿using SketchUpAPI.NET.Enums;
using SketchUpAPI.NET.SketchUp.Exception;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Lifetime;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace SketchUpAPI.NET.Objects
{
    /// <summary>
    /// 场景
    /// </summary>
    /// <remarks>对 SketchUpAPI 中的 SUSceneRef 的包装</remarks>
    public class Scene : Entity
    {
        #region API 函数
        /// <summary>
        /// 创建场景
        /// </summary>
        /// <param name="scene"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneCreate(out IntPtr scene);

        /// <summary>
        /// 释放场景
        /// </summary>
        /// <param name="scene"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneRelease(ref IntPtr scene);

        /// <summary>
        /// 获取是否使用相机
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_camera"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetUseCamera(IntPtr scene, out bool use_camera);

        /// <summary>
        /// 设置是否使用相机
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_camera"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetUseCamera(IntPtr scene, bool use_camera);

        /// <summary>
        /// 获取相机
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="camera"><see cref="Objects.Camera"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetCamera(IntPtr scene, out IntPtr camera);

        /// <summary>
        /// 设置相机
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="camera"><see cref="Objects.Camera"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetCamera(IntPtr scene, IntPtr camera);

        /// <summary>
        /// 获取是否包含到动画中
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="include_in_animation"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetIncludeInAnimation(IntPtr scene, out bool include_in_animation);

        /// <summary>
        /// 设置是否包含到动画中
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="include_in_animation"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetIncludeInAnimation(IntPtr scene, bool include_in_animation);

        /// <summary>
        /// 名字
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="name"><see cref="StringRef"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetName(IntPtr scene, ref IntPtr name);

        /// <summary>
        /// 设置名字
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="scene_name"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetName(IntPtr scene, [MarshalAs(UnmanagedType.LPUTF8Str)] string scene_name);

        /// <summary>
        /// 获取显示设置
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="options"><see cref="RenderingOptions"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetRenderingOptions(IntPtr scene, out IntPtr options);

        /// <summary>
        /// 获取阴影设置
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="shadow_info"><see cref="ShadowInfo"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetShadowInfo(IntPtr scene, out IntPtr shadow_info);

        /// <summary>
        /// 获取是否使用阴影设置
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_shadow_info"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetUseShadowInfo(IntPtr scene, out bool use_shadow_info);

        /// <summary>
        /// 设置是否使用阴影
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_shadow_info"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetUseShadowInfo(IntPtr scene, bool use_shadow_info);

        /// <summary>
        /// 获取是否使用显示设置
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_rendering_options"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetUseRenderingOptions(IntPtr scene, out bool use_rendering_options);

        /// <summary>
        /// 设置是否使用显示设置
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_rendering_options"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetUseRenderingOptions(IntPtr scene, bool use_rendering_options);

        /// <summary>
        /// 获取是否记录隐藏
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_hidden"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetUseHidden(IntPtr scene, out bool use_hidden);

        /// <summary>
        /// 设置是否记录隐藏
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_hidden"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetUseHidden(IntPtr scene, bool use_hidden);

        /// <summary>
        /// 获取是否使用隐藏物体
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_hidden"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetUseHiddenGeometry(IntPtr scene, out bool use_hidden);

        /// <summary>
        /// 设置是否使用隐藏物体
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_hidden"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetUseHiddenGeometry(IntPtr scene, bool use_hidden);

        /// <summary>
        /// 获取是否使用隐藏物件
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_hidden"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetUseHiddenObjects(IntPtr scene, out bool use_hidden);

        /// <summary>
        /// 设置是否记录隐藏物体
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_hidden"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetUseHiddenObjects(IntPtr scene, bool use_hidden);

        /// <summary>
        /// 获取是否使用隐藏图层
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_hidden_layers"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetUseHiddenLayers(IntPtr scene, out bool use_hidden_layers);

        /// <summary>
        /// 设置是否使用隐藏图层
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_hidden_layers"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetUseHiddenLayers(IntPtr scene, bool use_hidden_layers);

        /// <summary>
        /// 获取是否使用截平面
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_section_planes"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetUseSectionPlanes(IntPtr scene, out bool use_section_planes);

        /// <summary>
        /// 设置是否使用截平面
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_section_planes"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetUseSectionPlanes(IntPtr scene, bool use_section_planes);

        /// <summary>
        /// 获取图层个数
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetNumLayers(IntPtr scene, out int count);

        /// <summary>
        /// 获取全部图层
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="len"></param>
        /// <param name="layers"><see cref="Objects.Layer"/></param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetLayers(IntPtr scene, int len, IntPtr[] layers, out int realcount);

        /// <summary>
        /// 添加图层
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="layer"><see cref="Objects.Layer"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneAddLayer(IntPtr scene, IntPtr layer);

        /// <summary>
        /// 删除图层
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="layer"><see cref="Objects.Layer"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneRemoveLayer(IntPtr scene, IntPtr layer);

        /// <summary>
        /// 删除全部图层
        /// </summary>
        /// <param name="scene"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneClearLayers(IntPtr scene);

        /// <summary>
        /// 图层文件夹个数
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetNumLayerFolders(IntPtr scene, out int count);

        /// <summary>
        /// 获取全部图层文件夹
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="len"></param>
        /// <param name="layer_folders"><see cref="Objects.LayerFolder"/>[]</param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetLayerFolders(IntPtr scene, int len, IntPtr[] layer_folders, out int realcount);

        /// <summary>
        /// 添加图层文件夹
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="layer_folder"><see cref="Objects.LayerFolder"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneAddLayerFolder(IntPtr scene, IntPtr layer_folder);

        /// <summary>
        /// 移除图层文件夹
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="layer_folder"><see cref="Objects.LayerFolder"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneRemoveLayerFolder(IntPtr scene, IntPtr layer_folder);

        /// <summary>
        /// 移除全部图层文件夹
        /// </summary>
        /// <param name="scene"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneClearLayerFolders(IntPtr scene);

        /// <summary>
        /// 获取坐标系
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="axes"><see cref="Objects.Axes"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetAxes(IntPtr scene, out IntPtr axes);

        /// <summary>
        /// 设置是否使用坐标系
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_axes"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetUseAxes(IntPtr scene, bool use_axes);

        /// <summary>
        /// 获取是否使用坐标系
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="use_axes"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetUseAxes(IntPtr scene, out bool use_axes);

        /// <summary>
        /// 获取隐藏物体的个数
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetNumHiddenEntities(IntPtr scene, out int count);

        /// <summary>
        /// 获取全部隐藏物体
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="len"></param>
        /// <param name="entities"><see cref="Entity"/>[]</param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetHiddenEntities(IntPtr scene, int len, IntPtr[] entities, out int realcount);

        /// <summary>
        /// 设置标记
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="flags"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetFlags(IntPtr scene, int flags);

        /// <summary>
        /// 获取标记
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="flags"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetFlags(IntPtr scene, out int flags);

        /// <summary>
        /// 设置是否显示坐标系
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="displayed"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetSketchAxesDisplayed(IntPtr scene, bool displayed);

        /// <summary>
        /// 获取是否显示坐标系
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="displayed"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetSketchAxesDisplayed(IntPtr scene, out bool displayed);

        /// <summary>
        /// 获取是否显示照片匹配
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="displayed"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetPhotoMatchImageDisplayed(IntPtr scene, out bool displayed);

        /// <summary>
        /// 清除照片匹配
        /// </summary>
        /// <param name="scene"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneClearPhotoMatchImage(IntPtr scene);

        /// <summary>
        /// 获取样式
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="style"><see cref="Objects.Style"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetStyle(IntPtr scene, out IntPtr style);

        /// <summary>
        /// 复制场景设置
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="copy_scene"><see cref="Scene"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneCopy(IntPtr scene, IntPtr copy_scene);

        /// <summary>
        /// 激活场景
        /// </summary>
        /// <param name="scene"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneActivate(IntPtr scene);

        /// <summary>
        /// 设置物体是否隐藏
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="drawing_element"><see cref="DrawingElement"/></param>
        /// <param name="is_hidden"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetDrawingElementHidden(IntPtr scene, IntPtr drawing_element, bool is_hidden);

        /// <summary>
        /// 获取物体是否隐藏
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="drawing_element"></param>
        /// <param name="is_hidden"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetDrawingElementHidden(IntPtr scene, IntPtr drawing_element, out bool is_hidden);

        /// <summary>
        /// 获取描述
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="desc"><see cref="StringRef"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneGetDescription(IntPtr scene, ref IntPtr desc);

        /// <summary>
        /// 设置描述
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="desc"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUSceneSetDescription(IntPtr scene, [MarshalAs(UnmanagedType.LPUTF8Str)] string desc);
        #endregion

        /// <summary>
        /// 场景名字
        /// </summary>
        public string Name
        {
            get
            {
                StringRef s = StringRef.Empty;
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetName(Id, ref s.Id));
                return s.Dispose();
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetName(Id, value));
            }
        }

        /// <summary>
        /// 描述
        /// </summary>
        public string Description
        {
            get
            {
                StringRef s = StringRef.Empty;
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetDescription(Id, ref s.Id));
                return s.Dispose();
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetDescription(Id, value));
            }
        }

        /// <summary>
        /// 标记
        /// </summary>
        public int Flags
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetFlags(Id, out int f));
                return f;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetFlags(Id, value));
            }
        }

        /// <summary>
        /// 显示设置
        /// </summary>
        public RenderingOptions RenderingOptions
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetRenderingOptions(Id, out IntPtr id));
                return new RenderingOptions(id);
            }
        }

        /// <summary>
        /// 使用显示设置
        /// </summary>
        public bool UseRenderingOptions
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetUseRenderingOptions(Id, out bool u));
                return u;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetUseRenderingOptions(Id, value));
            }
        }

        /// <summary>
        /// 阴影设置
        /// </summary>
        public ShadowInfo ShadowInfo
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetShadowInfo(Id, out IntPtr id));
                return new ShadowInfo(id);
            }
        }

        /// <summary>
        /// 使用阴影设置
        /// </summary>
        public bool UseShadowInfo
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetUseShadowInfo(Id, out bool u));
                return u;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetUseShadowInfo(Id, value));
            }
        }

        /// <summary>
        /// 相机
        /// </summary>
        public Camera Camera
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetCamera(Id, out IntPtr c));
                return new Camera(c);
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetCamera(Id, value.Id));
            }
        }

        /// <summary>
        /// 是否使用相机
        /// </summary>
        public bool UseCamera
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetUseCamera(Id, out bool uc));
                return uc;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetUseCamera(Id, value));
            }
        }

        /// <summary>
        /// 是否包含到动画
        /// </summary>
        public bool IncludeInAnimation
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetIncludeInAnimation(Id, out bool uc));
                return uc;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetIncludeInAnimation(Id, value));
            }
        }

        /// <summary>
        /// 全部隐藏物体
        /// </summary>
        public List<Entity> HiddenEntities
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetNumHiddenEntities(Id, out int count));
                IntPtr[] pts = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetHiddenEntities(Id, count, pts, out _));
                return pts.Select(i => new Entity(i)).ToList();
            }
        }

        /// <summary>
        /// 是否记录隐藏
        /// </summary>
        public bool UseHidden
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetUseHidden(Id, out bool u));
                return u;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetUseHidden(Id, value));
            }
        }

        /// <summary>
        /// 是否记录隐藏物体
        /// </summary>
        public bool UseHiddenGeometry
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetUseHiddenGeometry(Id, out bool u));
                return u;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetUseHiddenGeometry(Id, value));
            }
        }

        /// <summary>
        /// 是否记录隐藏物体
        /// </summary>
        public bool UseHiddenObject
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetUseHiddenObjects(Id, out bool u));
                return u;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetUseHiddenObjects(Id, value));
            }
        }

        /// <summary>
        /// 记录隐藏图层
        /// </summary>
        public bool UseHiddenLayer
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetUseHiddenLayers(Id, out bool u));
                return u;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetUseHiddenLayers(Id, value));
            }
        }

        /// <summary>
        /// 是否记录截平面
        /// </summary>
        public bool UseSectionPlane
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetUseSectionPlanes(Id, out bool u));
                return u;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetUseSectionPlanes(Id, value));
            }
        }

        /// <summary>
        /// 全部图层
        /// </summary>
        public List<Layer> Layers
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetNumLayers(Id, out int count));
                IntPtr[] pts = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetLayers(Id, count, pts, out _));
                return pts.Select(i => new Layer(i)).ToList();
            }
        }

        /// <summary>
        /// 全部图层文件夹
        /// </summary>
        public List<LayerFolder> LayerFolders
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetNumLayerFolders(Id, out int count));
                IntPtr[] pts = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetLayerFolders(Id, count, pts, out _));
                return pts.Select(i => new LayerFolder(i)).ToList();
            }
        }

        /// <summary>
        /// 坐标系
        /// </summary>
        public Axes Axes
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetAxes(Id, out IntPtr id));
                return new Axes(id);
            }
        }

        /// <summary>
        /// 是否使用坐标系
        /// </summary>
        public bool UseAxes
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetUseAxes(Id, out bool u));
                return u;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetUseAxes(Id, value));
            }
        }

        /// <summary>
        /// 是否显示坐标系
        /// </summary>
        public bool AxesDisplayed
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetSketchAxesDisplayed(Id, out bool d));
                return d;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneSetSketchAxesDisplayed(Id, value));
            }
        }

        /// <summary>
        /// 是否显示照片匹配
        /// </summary>
        public bool PhotoMatchImageDisplayed
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetPhotoMatchImageDisplayed(Id, out bool d));
                return d;
            }
        }

        /// <summary>
        /// 样式
        /// </summary>
        public Style Style
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUSceneGetStyle(Id, out IntPtr s));
                return new Style(s);
            }
        }

        public Scene()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneCreate(out Id));
        }

        internal Scene(IntPtr id) => Id = id;

        /// <summary>
        /// 添加图层
        /// </summary>
        /// <param name="layer"></param>
        public void Add(Layer layer)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneAddLayer(Id, layer.Id));
        }

        /// <summary>
        /// 添加图层文件夹
        /// </summary>
        /// <param name="folder"></param>
        public void Add(LayerFolder folder)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneAddLayerFolder(Id, folder.Id));
        }

        /// <summary>
        /// 移除图层
        /// </summary>
        /// <param name="layer"></param>
        public void Remove(Layer layer)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneRemoveLayer(Id, layer.Id));
        }

        /// <summary>
        /// 移除图层文件夹
        /// </summary>
        /// <param name="folder"></param>
        public void Remove(LayerFolder folder)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneRemoveLayerFolder(Id, folder.Id));
        }

        /// <summary>
        /// 删除全部图层
        /// </summary>
        public void ClearLayers()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneClearLayers(Id));
        }

        /// <summary>
        /// 清除全部图层文件夹
        /// </summary>
        public void ClearLayerFolders()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneClearLayerFolders(Id));
        }

        /// <summary>
        /// 清除照片匹配
        /// </summary>
        public void ClearPhotoMatchImage()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneClearPhotoMatchImage(Id));
        }

        /// <summary>
        /// 从另一个场景复制设置
        /// </summary>
        /// <param name="other"></param>
        public void CopyData(Scene other)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneCopy(Id, other.Id));
        }

        /// <summary>
        /// 激活场景
        /// </summary>
        public void Activate()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneActivate(Id));
        }

        /// <summary>
        /// 设置物体是否隐藏
        /// </summary>
        /// <param name="element"></param>
        /// <param name="hidden">是否隐藏</param>
        public void SetElementHidden(DrawingElement element, bool hidden)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneSetDrawingElementHidden(Id, element.Id, hidden));
        }

        /// <summary>
        /// 获取物体是否被隐藏了
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public bool GetElementHidden(DrawingElement element)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneGetDrawingElementHidden(Id, element.Id, out bool h));
            return h;
        }

        public override void Dispose()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUSceneRelease(ref Id));
        }
    }
}